class MVVM {
  constructor(options) {
    // 挂载实例
    this.$el = options.el;
    this.$data = this.getBaseType(options.data) === 'Object' ? options.data : {};
    this.$watch = this.getBaseType(options.watch) === 'Object' ? options.watch : {};

    // 编译模板
    if (this.$el) {
      // 数据劫持 把对象的所有属性 改成带set 和 get 方法的
      new Observer(this.$data, this)
      // 将数据代理到实例上，直接操作实例即可，不需要通过vm.$data来进行操作
      this.proxyData(this.$data)
      //如果有methods
      if (options.methods) {
        Object.keys(options.methods).map(methodName => {
          this[methodName] = options.methods[methodName].bind(this)
        })
      }
      //如果有created
      if (options.created) {
        options.created.call(this);
      }
      // 用数据和元素进行编译
      new Compile(this.$el, this)
      //如果有如果有mounted
      if (options.mounted) {
        options.mounted.call(this);
      }
    }


  }

  getBaseType (target) {
    const typeStr = Object.prototype.toString.apply(target);

    return typeStr.slice(8, -1);
  }

  proxyData (data) {
    Object.keys(data).forEach(key => {
      Object.defineProperty(this, key, {
        get () {
          return data[key]
        },
        set (newValue) {
          data[key] = newValue
        }
      })
    })
  }
}